part of internal;

class Line {
   DivElement _line;
   DivElement _cur;
   DivElement _sel;
   SpanElement _let;

   // generator
   Line (String tok) {
      // initialize and style
      _line = new DivElement();
      _line.style
         ..flexBasis = '1em'
         ..flexShrink = '0';
      _cur = new DivElement();
      _cur.style
         ..position = 'absolute'
         ..width = '1px'
         ..height = '1em'
         ..backgroundColor = 'black'
         ..display = 'none';
      _sel = new DivElement();
      _sel.style
         ..position = 'absolute'
         ..height = '1em'
         ..backgroundColor = 'lightgrey'
         ..zIndex = '-1'
         ..display = 'none';
      _let = new SpanElement();
      _let.nodes.add(new Text(tok));
      // add to line container
      _line.children.add(_cur);
      _line.children.add(_sel);
      _line.children.add(_let);
      if (dev) if (!valid) staErr(this);
   }

   // mutators
   void curOn (int ch) {
      if (dev) if (ch == null) argErr(ch);
      _cur.style.left = (ch / 2.0).toString() + 'em';
      _cur.style.display = 'initial';
      if (dev) if (!valid) staErr(this);
   }
   void curOff () {
      _cur.style.display = 'none';
      if (dev) if (!valid) staErr(this);
   }
   void selOn (int left, int right) {
      if (dev) {
         if (left == null) argErr(left);
         if (right == null) argErr(right);
      }
      _sel.style.left = (left / 2.0).toString() + 'em';
      _sel.style.width = ((right - left) / 2.0).toString() + 'em';
      _sel.style.display = 'initial';
      if (dev) if (!valid) staErr(this);
   }
   void selOff () {
      _sel.style.display = 'none';
      if (dev) if (!valid) staErr(this);
   }
   void set let (String tok) {
      (_let.nodes.first as Text).data = tok;
      if (dev) if (!valid) staErr(this);
   }

   // observers
   DivElement get line => _line;

   // invariants
   bool get valid {
      return true;
   }

   // printing
   String toString () => 'RenderedLine';
}
